using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using Avalonia.Controls;
using ReactiveUI;
using SocketTool.Helper;
using SocketTool.Model.BindingModels;

namespace SocketTool.ViewModels.ControlViewModel
{
    public class ReqMessageParamViewModel : ViewModelBase
    {
        #region Properties

        private bool mSelectedJsonParam;

        /// <summary>
        /// 选中json参数
        /// </summary>
        public bool SelectedJsonParam
        {
            get => this.mSelectedJsonParam;
            set
            {
                this.RaiseAndSetIfChanged(ref this.mSelectedJsonParam, value);
                if (value)
                {
                    this.InitJsonParamFromText();
                }
            }
        }

        private bool mSelectedTextParam;

        /// <summary>
        /// 选中text文本参数
        /// </summary>
        public bool SelectedTextParam
        {
            get => this.mSelectedTextParam;
            set
            {
                this.RaiseAndSetIfChanged(ref this.mSelectedTextParam, value);
                if (value)
                {
                    this.InitTextParamFromJson();
                }
            }
        }


        private string mReqParamText;

        /// <summary>
        /// Text格式的请求参数
        /// </summary>
        public string ReqParamText
        {
            get => this.mReqParamText;
            set => this.RaiseAndSetIfChanged(ref mReqParamText, value);
        }

        /// <summary>
        /// 请求参数列表
        /// </summary>
        public ObservableCollection<ReqParamBindingModel> ParamsList { get; set; }

        /// <summary>
        /// 界面TreeDataGrid绑定使用的类
        /// </summary>
        public HierarchicalTreeDataGridSource<ReqParamBindingModel> TreeDataGridSource { get; private set; }

        #endregion

        #region Commands

        /// <summary>
        /// Json参数添加兄弟节点
        /// </summary>
        public ReactiveCommand<ReqParamBindingModel, Unit> AddBortherParamCommand { get; private set; }

        /// <summary>
        /// Json参数添加子节点
        /// </summary>
        public ReactiveCommand<ReqParamBindingModel, Unit> AddChildParamCommand { get; private set; }

        /// <summary>
        /// Json参数删除节点
        /// </summary>
        public ReactiveCommand<ReqParamBindingModel, Unit> RemoveParamCommand { get; private set; }

        #endregion


        public ReqMessageParamViewModel()
        {
            this.ParamsList = new ObservableCollection<ReqParamBindingModel>();
            this.ParamsList.Add(new ReqParamBindingModel()
            {
                Key = "",
                Value = "",
                ValueType = (int) Model.Enums.JsonValueTypeEnum.String,
                IsChecked = true,
                Explan = ""
            });

            this.AddBortherParamCommand = ReactiveCommand.Create<ReqParamBindingModel>(addBortherParam);
            this.AddChildParamCommand = ReactiveCommand.Create<ReqParamBindingModel>(addChildParam);
            this.RemoveParamCommand = ReactiveCommand.Create<ReqParamBindingModel>(removeParam);

            this.TreeDataGridSource =
                Helper.TreeDataGridHelper.CreateHierachicalColumns(this.ParamsList, nameof(AddBortherParamCommand),
                    nameof(AddChildParamCommand), nameof(RemoveParamCommand));
        }


        void addBortherParam(ReqParamBindingModel model)
        {
            if (model == null)
                return;

            //表示是直接添加到根目录下
            if (model.Parent == null)
            {
                this.ParamsList.Add(new ReqParamBindingModel()
                {
                    ValueType = (int) SocketTool.Model.Enums.JsonValueTypeEnum.String
                });
            }
            else
            {
                model.Parent.Children.Add(new ReqParamBindingModel(model.Parent)
                {
                    ValueType = (int) SocketTool.Model.Enums.JsonValueTypeEnum.String
                });
            }
        }

        void addChildParam(ReqParamBindingModel model)
        {
            if (model == null)
                return;

            //只能当值类型为Object或ObjectArray时才能添加子集
            if (model.ValueType != (int) SocketTool.Model.Enums.JsonValueTypeEnum.Object &&
                model.ValueType != (int) SocketTool.Model.Enums.JsonValueTypeEnum.ObjectArray)
            {
                SocketTool.Controls.GrowlControl.Warning("值类型必须为Object或者ObjectArray才能添加子集");
                return;
            }
            model.Children.Add(new ReqParamBindingModel(model)
            {
                ValueType = (int) SocketTool.Model.Enums.JsonValueTypeEnum.String
            });
            model.HasChild = true;
        }

        void removeParam(ReqParamBindingModel model)
        {
            if (model == null)
                return;
            if (model.Parent == null)
            {
                this.ParamsList.Remove(model);
                if (this.ParamsList.Count < 1)
                {
                    this.ParamsList.Add(new ReqParamBindingModel()
                    {
                        ValueType = (int) SocketTool.Model.Enums.JsonValueTypeEnum.String
                    });
                }
            }
            else
            {
                model.Parent.Children.Remove(model);
                if (model.Parent.Children.Count < 1)
                    model.HasChild = false;
            }
        }

        public void ClearParam()
        {
            this.ReqParamText = string.Empty;
            this.SelectedJsonParam = true;
            this.ParamsList.Clear();
            this.ParamsList.Add(new ReqParamBindingModel()
            {
                Key = "",
                Value = "",
                ValueType = (int) Model.Enums.JsonValueTypeEnum.String,
                IsChecked = true,
                Explan = ""
            });
        }
        
        /// <summary>
        /// 从字符串转换成集合
        /// </summary>
        public void InitJsonParamFromText()
        {
            try
            {
                if (string.IsNullOrEmpty(this.ReqParamText))
                    return;
                var list = TreeDataGridHelper.Text2Json(this.ReqParamText);
                if (list != null)
                {
                    this.ParamsList.Clear();
                    foreach (var item in list)
                    {
                        this.ParamsList.Add(item);
                    }

                    if (this.ParamsList.Count < 1)
                        this.ParamsList.Add(new ReqParamBindingModel());
                }
            }
            catch (Exception ex)
            {
               SocketTool.Controls.GrowlControl.Error($"转换失败  {ex.Message}");
            }
        }

        /// <summary>
        /// 从集合转换成字符串
        /// </summary>
        public void InitTextParamFromJson()
        {
            if (this.ParamsList.Count < 1)
                return;
            if (Helper.TreeDataGridHelper.CheckHasRepeatKey(this.ParamsList))
            {
                SocketTool.Controls.GrowlControl.Error("同一层级内不可添加重复键");
                return;
            }
            this.ReqParamText = Helper.TreeDataGridHelper.Json2Texts(this.ParamsList).ToString();
        }

        /// <summary>
        /// 动态设置协议
        /// </summary>
        /// <param name="list"></param>
        public void SetJsonParam(IList<ReqParamBindingModel> list)
        {
            this.ParamsList.Clear();
            if (Helper.TreeDataGridHelper.CheckHasRepeatKey(list))
            {
                SocketTool.Controls.GrowlControl.Error("同一层级内不可添加重复键");
                return;
            }
            foreach (var item in list)
            {
                this.ParamsList.Add(item);
            }
            
            if(list.Count > 0)
                this.InitTextParamFromJson();
        }
        
    }
}